home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Classic
/
CD CLASSIC #1.iso
/
3df
/
3df.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-20
|
14KB
|
472 lines
{ 3dF --- Simple viewer for real functions of form F(x,y). }
{ Parse an expression to form a syntax tree. Walk the tree }
{ to evaluate the expression on a grid over the x-y plane. }
{ Draw orthographic projection with hidden lines removed, }
{ view angle, etc. adjustable by user with cursor controls. }
{ Disclaimer: This code is a mess. It was written in a }
{ very short time to prove that expensive hardware was not }
{ required for a specific purpose. Let the user beware. }
{ Compile with TP 5.0. }
Program p3dF;
Uses Crt, Parse;
{ Assembly language assist. According to tprof, most
opportunity for getting faster is in DrawLine,
especially Plot (on my 4.77Mhz 8088 w/o NCP). }
procedure SetVideo(mode: Byte); external;
procedure ClearScreen; external;
procedure SetPallette(pal: Byte); external;
procedure SetBackGround(color: Byte); external;
procedure MovePen(x, y: Word); external;
procedure DrawLine(x, y: Word); external;
procedure InitCloud; external;
procedure UpdateCloud; external;
procedure ClearImage; external;
procedure ShowImage; external;
{$ifdef profile}
procedure initx; external;
procedure inity; external;
procedure initXinc; external;
procedure initYinc; external;
procedure plot; external;
{$endif}
{$L 3df.obj}
const
nGrids = 15; { make me 10 for faster displays of fewer grids }
DevP = 192; { vertical device size in pixels }
StepsInQuad = 18;
IntScale = 32;
ScaleBits = 5;
ScaleBitsM1 = 4; { scale bits minus 1 (accounts for 2/1 aspect of pixels) }
pi = 3.1415926535897932385; { Save fun call time. }
var
eData: array[-nGrids..nGrids, -nGrids..nGrids] of Real;
eMin, eMax: Real;
yData: array[0..3, -nGrids..nGrids, -nGrids..nGrids] of Integer;
scrImg: array[0..199, 0..79] of Byte;
baseXTbl,
baseYTbl,
deltaXiTbl,
deltaYiTbl,
deltaXjTbl, { how much to inc x for step in j }
deltaYjTbl: array[0..StepsInQuad] of Integer; { how much to inc y for step in j }
procedure FillGrid(size, exag: Real; phi: Integer);
var
e, de, i, j: Integer;
sPhi, cPhi,
imageHt, imageWd,
unitsToDev, eScale,
theta, dTheta, sTheta, cTheta, sizeP, scaleFac: Real;
begin
sPhi := Sin(phi*pi/180);
cPhi := Cos(phi*pi/180);
{ 1.5 is really sqrt(2)*fudge to _ensure_ images lie in screen. }
imageHt := sPhi*size*1.5+cPhi*(eMax-eMin)*exag;
imageWd := size*1.5;
if imageHt > imageWd/1.6 then
unitsToDev := DevP/imageHt
else
unitsToDev := DevP*1.6/imageWd;
sizeP := size*unitsToDev;
eScale := exag*unitsToDev*cPhi*IntScale;
for i := -nGrids to nGrids do
for j := -nGrids to nGrids do begin
e := Round((eData[i,j]-eMin)*eScale);
yData[0, i, j] := e;
yData[1, j,-i] := e;
yData[2, -i,-j] := e;
yData[3, -j, i] := e;
end;
theta := 0;
dTheta := (pi/2)/StepsInQuad;
scaleFac := sizeP/(nGrids+nGrids)*IntScale;
for i := 0 to stepsInQuad-1 do begin
sTheta := scaleFac*Sin(theta);
cTheta := scaleFac*Cos(theta);
deltaXiTbl[i] := Round(sTheta);
deltaYiTbl[i] := Round(cTheta*sPhi);
deltaXjTbl[i] := Round(cTheta);
deltaYjTbl[i] := Round(sTheta*sPhi);
baseXtbl[i] := Round((sizeP*0.707*Cos(theta+pi/4)+160)*IntScale);
baseYtbl[i] := Round((DevP-sizeP*0.707*(1-Sin(theta+pi/4))*sPhi)*IntScale);
theta := theta+dTheta;
end;
end;
procedure DrawIt(cx, cy, size: Real);
const
initStep = 4;
initDstep = 1;
initQuad = 1;
initPhi = 20;
initExag = 1;
var
exag: Real;
i, j, phi,
step, quad, dStep, x00, y00, x0, y0, x, y, tx, ty,
px, py0, py, lastPx, lastPy0, dxi, dyi, dxj, dyj: Integer;
lastCutX, lastCutY: array[-nGrids..nGrids] of Integer;
ch: Char;
procedure WritePhi;
begin
GoToXY(19, 25);
Write(phi:2);
end;
procedure WriteExag;
begin
GoToXY(36, 25);
Write(exag:3:1);
end;
begin
DirectVideo := False;
dStep := initDstep;
step := initStep;
quad := initQuad;
phi := initPhi;
exag := initExag;
FillGrid(size, exag, phi);
SetVideo(6); { 640 x 200 }
ClearScreen;
GoToXY(1, 25);
Write(
'eXit '#27#26'rot '#24#25'elev(__) PgUp/Dn exag(___) ',
'x ',cx:0:2, ' y ', cy:0:2, ' sz ', size:0:2,
' f ', eMin:0:2, '/', eMax:0:2);
WritePhi;
WriteExag;
repeat
ClearImage;
InitCloud;
x0 := baseXtbl[step];
x00 := x0;
y0 := baseYtbl[step];
y00 := y0;
dxi := deltaXiTbl[step];
dyi := deltaYiTbl[step];
dxj := deltaXjTbl[step];
dyj := deltaYjTbl[step];
{ draw first cut }
y := y0;
x := x0;
px := x shr ScaleBitsM1;
py0 := y shr ScaleBits;
py := (y-yData[quad, -nGrids,-nGrids]) shr ScaleBits;
MovePen(px, py0);
DrawLine(px, py);
lastPx := px;
lastPy0 := py0;
lastCutX[-nGrids] := px;
lastCutY[-nGrids] := py;
for j := -nGrids+1 to nGrids do begin
x := x - dxj;
y := y - dyj;
px := x shr ScaleBitsM1;
py0 := y shr ScaleBits;
py := (y-yData[quad, -nGrids, j]) shr ScaleBits;
DrawLine(px, py);
DrawLine(px, py0);
MovePen(lastPx, lastPy0);
DrawLine(px, py0);
if j = 0 then
if Odd(quad) then begin
tx := x-dxi*3;
ty := y+dyi*3;
DrawLine(tx shr ScaleBitsM1, ty shr ScaleBits);
if quad = 1 then begin
DrawLine((tx-dxi+dxj) shr ScaleBitsM1,
(ty+dyi+dyj) shr ScaleBits);
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
DrawLine((tx-dxi-dxj) shr ScaleBitsM1,
(ty+dyi-dyj) shr ScaleBits);
end
else begin
DrawLine((tx+dxi+dxj) shr ScaleBitsM1,
(ty-dyi+dyj) shr ScaleBits);
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
DrawLine((tx+dxi-dxj) shr ScaleBitsM1,
(ty-dyi-dyj) shr ScaleBits);
end;
end;
MovePen(px, py);
lastPx := px;
lastPy0 := py0;
lastCutX[j] := px;
lastCutY[j] := py;
end;
UpdateCloud;
lastPx := x00 shr ScaleBitsM1;
lastPy0 := y00 shr ScaleBits;
for i := -nGrids+1 to nGrids do begin
x0 := x0+dxi;
y0 := y0-dyi;
y := y0;
x := x0;
px := x shr ScaleBitsM1;
py0 := y shr ScaleBits;
py := (y-yData[quad, i,-nGrids]) shr ScaleBits;
MovePen(lastPx, lastPy0);
DrawLine(px, py0);
lastPx := px;
lastPy0 := py0;
if (i = 0) and (quad and 1 = 0) then begin
tx := x+dxj*3;
ty := y+dyj*3;
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
if quad = 0 then begin
DrawLine((tx+dxj-dxi) shr ScaleBitsM1,
(ty+dyj+dyi) shr ScaleBits);
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
DrawLine((tx+dxj+dxi) shr ScaleBitsM1,
(ty+dyj-dyi) shr ScaleBits);
end
else begin
DrawLine((tx-dxj-dxi) shr ScaleBitsM1,
(ty-dyj+dyi) shr ScaleBits);
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
DrawLine((tx-dxj+dxi) shr ScaleBitsM1,
(ty-dyj-dyi) shr ScaleBits);
end;
MovePen(tx shr ScaleBitsM1, ty shr ScaleBits);
DrawLine(px, py0);
end;
DrawLine(px, py);
DrawLine(lastCutX[-nGrids], lastCutY[-nGrids]);
UpdateCloud;
MovePen(px, py);
lastCutX[-nGrids] := px;
lastCutY[-nGrids] := py;
for j := -nGrids+1 to nGrids do begin
x := x - dxj;
y := y - dyj;
px := x shr ScaleBitsM1;
py := (y-yData[quad, i, j]) shr ScaleBits;
DrawLine(px, py);
DrawLine(lastCutX[j], lastCutY[j]);
MovePen(px, py);
lastCutX[j] := px;
lastCutY[j] := py;
UpdateCloud;
end;
end;
if KeyPressed then begin
ch := ReadKey;
if ch = #0 then begin
ch := ReadKey;
case ch of
#77: if dStep > -3 then { right arrow }
dStep := dStep-1;
#75